#include "stdio.h"

#include "../port/master_ctr_circuit_node.h"


////////////////////////
#include <string.h>
#include "./config/config_by_device_type.h"
#include "./config/dev_table_by_config.h"
#include "./utils/list_node.h"
#include "./front_back_interfaction/rt_record.h"

/////////////////////////

void get_node_ptr_from_addr();
void TEST_find_91A_node_then_init_and_event_list_append();
//void TEST_rt_data_event_list_append();
void TEST_auto_find_node_by_muti_address();
void init_master_tree_and_find_node_by_muti_addr();
void init_master_tree_and_append_event_in_91A_rt_list();

int main()
{   
     
       get_node_ptr_from_addr();
       //init_master_tree_and_append_event_in_91A_rt_list();
       // init_master_tree_and_find_node_by_muti_addr();

     printf("bybye\n");
}



/*************************************************************************
 *  单元测试
*************************************************************************/

/**
 * @brief Get the node ptr from addr object
 * 使用 多级地址：回路号+节点号，来获得节点树中指定节点。
 * 使用 91设备地址： 主机号+中继号+节点号 获得节点树中指定地址。
 * 当返回的节点指针为NULL 则代表未能找到指定节点。
 * 
 */
void get_node_ptr_from_addr()
{
       /**> 1、 读取配置文件，节点树初始化 */ 
       init_node_tree_by_config_file();

       /**> 2、使用91A中的节点地址类型来寻找节点 */ 
       find_91a_node_t dev_addr =
       {
              .dev_addr.master_index = 11,
              .dev_addr.relay_index = RELAY_ORDER_INVAILD,
              .dev_addr.node_index = 8,
              .node_ptr = NULL
       };
       
       /**> 2.1、使用91A中的节点地址类型来寻找节点  */ 
       get_node_from_master_tree_by_91a_dev_addr(&dev_addr);

       if(dev_addr.node_ptr != NULL)
       {
              printf("%s \n",dev_addr.node_ptr->dev_description);
       }
       else
       {
              error_log("not find node ");
       }
      

       /**> 3、 创建一个多级地址 当前这个是 找 90A-91A-中继模块-07A */
       circuit_node_addr_t addr_90A_91a_07A[] = {                          \
                                        {SELF_CIRCUIT_CAN_OUT1, 2},\
                                        {MOD_91A_CIRCUIT_PDFB2,10}, \
                                        {MOD_RELAY_MOD_CIRCUIT,4}\
                                };

      muti_addr_t node_addr;                          
    /**> 3.1、填充多级地址指针 */
       node_addr.addr_arry_ptr = addr_90A_91a_07A;
    /**> 3.2、填充多级地址 级数 */
       node_addr.addr_num = ARRY_SIZE(addr_90A_91a_07A);

    /**> 3.3、调用函数 通过多级地址查找节点，要保证多级地址是正确的，否则找不到对应的节点 */
       get_node_from_master_tree_by_muti_addr(&node_addr);

    /**> 当找到对应节点后 */
    if( node_addr.node_ptr)
    {
        /**> 可以直接读 这个节点结构体内包含的东西： 设备描述 */
        printf("07A name %s \n",node_addr.node_ptr->dev_description);

    }
}



void record_list()
{
         rt_record_init();

        report_data_t data1 = 
        {
                .evt_type = 1,
                .dev_addr.master_index = 111,
                .dev_addr.node_index = 2,
                .dev_addr.relay_index = 3,
                .occur_time = get_century_seconds()
        };

        report_data_t data222;

       for (int i = 0; i < 10; i++)
       {
            data1.evt_type = i;
            record_add_list(PageActiveEvt, data1);

       }

       for (int i = 1; i <= 10; i++)
       {
           record_read(PageActiveEvt, i, &data222);
              printf("- %d \n", data222.evt_type);
       }
}










/**
 * @brief 初始化 节点树，然后找到一个91A节点，向其中添加事件信息，然后读出来
 * 
 */
void init_master_tree_and_append_event_in_91A_rt_list()
{

   // 初始化节点树
    init_node_tree_by_config_file();

    // 配置多级地址
    muti_addr_t node_addr;
    circuit_node_addr_t addr_90A_91a[] = {                       \
                                        {SELF_CIRCUIT_CAN_IN1, 9} \
                                        };

    node_addr.addr_arry_ptr = addr_90A_91a;
    node_addr.addr_num = ARRY_SIZE(addr_90A_91a);

    // 取得91A节点
    get_node_from_master_tree_by_muti_addr(&node_addr);

    if( node_addr.node_ptr)
    {
        circuit_node_t  *temp_node = node_addr.node_ptr ;

        node_operate_irf_t       *op_ptr;       /** 模块的操作函数指针 */

        /** 获得91A模块的操作函数指针 */
        op_ptr = get_op_irf_by_circuit_node_type(temp_node->node_type);

        /**> 创建一些事件节点，事件的时间使用世纪秒保存 */
         report_data_t data1 = 
        {
                .evt_type = 1,
                .dev_addr.master_index = 11,
                .dev_addr.node_index = 2,
                .dev_addr.relay_index = 3,
                .occur_time = get_century_seconds()
        };

         report_data_t data2 = 
        {
                .evt_type = 1,
                .dev_addr.master_index = 22,
                .dev_addr.node_index = 2,
                .dev_addr.relay_index = 3,
                .occur_time = get_century_seconds()
        };

         report_data_t data3 = 
        {
                .evt_type = 1,
                .dev_addr.master_index = 33,
                .dev_addr.node_index = 2,
                .dev_addr.relay_index = 3,
                .occur_time = get_century_seconds()
        };

         report_data_t data4 = 
        {
                .evt_type = 1,
                .dev_addr.master_index = 44,
                .dev_addr.node_index = 2,
                .dev_addr.relay_index = 3,
                .occur_time = get_century_seconds()
        };

        /**> 使用模块操作函数进行添加事件，使用特殊操作码：OP_CODE_90A_EVENT_LIST_ADD */
        op_ptr->irfIoCtrl(temp_node, OP_CODE_90A_EVENT_LIST_ADD, &data1);
        op_ptr->irfIoCtrl(temp_node, OP_CODE_90A_EVENT_LIST_ADD, &data2);
        op_ptr->irfIoCtrl(temp_node, OP_CODE_90A_EVENT_LIST_ADD, &data3);
        op_ptr->irfIoCtrl(temp_node, OP_CODE_90A_EVENT_LIST_ADD, &data4);

        /**> 把这个节点的链表数据读出 */
        RT_DATA_TYPE(TYPE_CTR_CW1320_91A) *rt_91A = temp_node->node_rt_data;
        list_head_node *list = &rt_91A->gas_exth_zone_1.gaszone_evt_list;
        
        // 建一个用于读取的变量
         report_data_t data_read;

        for(int num = 1; num < 5; num++)
        {
                LIST_READ(REPORT_DATA_91A)(list, POSI_READ, num, &data_read) ;

                printf("%d \n", data_read.dev_addr.master_index);
        }
    }
    else
    {
            printf("the node is null\n");
    }
}


void node_get_uc_code(config_data_store_t  *config_data)
{
    /**> 确定对应设备类型，创建对应类型的配置变量*/
            CONFIG_INFO_TYPE(TYPE_SENSOR_07A_SLAVE) config_07A;
            
    /**> 将类型转换一下，读出其中的UC码，注意这里UC码是用字符串保存  */
            config_07A = config_data->config_data_store_ptr->TYPE_SENSOR_07A_SLAVE_info_config;
            printf("07A uc code %s\n",config_07A.UC_code);
}

/**
 * @brief 初始化节点树，并根据多级地址，找到其中的一个节点，读出节点的设备描述、UC码
 * 
 * 注意，多级地址指向的节点必须要有，否则找不到
 * 
 */
void init_master_tree_and_find_node_by_muti_addr()
{
    /**> 根据配置文件生成节点树 */
      init_node_tree_by_config_file();

    /**> 确认配置成功，不成功，后边都会失败，不允许执行 */
       printf("config flag %d\n",is_config_sucess());
       
    /**> 创建一个多级地址变量，用于存储多级地址 */
    muti_addr_t node_addr;
    /**> 创建一个 配置数据变量，用于保存读出的节点配置信息 */
    config_data_store_t  config_data;


    /**>  创建一个多级地址 当前这个是 找 90A-91A-中继模块-07A */
    circuit_node_addr_t addr_90A_91a_07A[] = {                          \
                                        {SELF_CIRCUIT_CAN_OUT1, 2},\
                                        {MOD_91A_CIRCUIT_PDFB2,9}, \
                                        {MOD_RELAY_MOD_CIRCUIT,4}\
                                };
    /**> 填充多级地址指针 */
       node_addr.addr_arry_ptr = addr_90A_91a_07A;
    /**> 填充多级地址 级数 */
       node_addr.addr_num = ARRY_SIZE(addr_90A_91a_07A);
    /**> 调用函数 通过多级地址查找节点，要保证多级地址是正确的，否则找不到对应的节点 */
       get_node_from_master_tree_by_muti_addr(&node_addr);

    /**> 当找到对应节点后 */
    if( node_addr.node_ptr)
    {
        /**> 可以直接读 这个节点结构体内包含的东西： 设备描述 */
        printf("07A name %s \n",node_addr.node_ptr->dev_description);

        /**> 使用这个函数 获得这个节点中的配置信息。
         * 因为节点的配置信息是用void指针通过动态分配得到的空间
         * */
        get_node_config_data(node_addr.node_ptr, &config_data);

        /**> 取出信息后，判断是否取出，并根据具体类型来区分分析 */
        if(config_data.config_data_store_ptr)
        {
            switch (config_data.node_type)
            {
                case TYPE_SENSOR_07A_SLAVE:
                
                /** TODO: 这里通过调用函数来获取变量里的数据吧，
                 * 把节点传入，然后根据传入不同类型的函数，获得不同设备类型的数据 */

                node_get_uc_code(&config_data);

                break;
                
                default:
                break;
            }
        }
    }


}







void get_91A_node_info_and_find_one_node()
{

// for(int i = 0; i< 2; i++)
// {
//        for (int j = 0; j < get_master_tree_node_index(i); j++)
//        {

//               CONFIG_INFO_TYPE(TYPE_CTR_CW1320_91A) *temp_cfg_para =\
//                      (CONFIG_INFO_TYPE(TYPE_CTR_CW1320_91A)*) MasterNodeTree[i][j].node_config_data;

//               printf(" ID: %d, index %d, dev_description %s \n",\
//                              i,j, MasterNodeTree[i][j].dev_description);

//               printf(" -ID: %d, -index %d,  \n", \
//                             MasterNodeTree[i][j].node_addr.circuit_ID,\
//                             MasterNodeTree[i][j].node_addr.circuit_node_index);    

//               printf(" para %s \n", temp_cfg_para->config_file_name);
           
//        }   
// }
      
//        muti_addr_t node_addr;
//        circuit_node_addr_t addr_90A_91a[] = {                          \
//                                           {SELF_CIRCUIT_CAN_IN1, 9} \
//                                           };

//        node_addr.addr_arry_ptr = addr_90A_91a;
//        node_addr.addr_num = ARRY_SIZE(addr_90A_91a);

//        get_node_from_master_tree_by_muti_addr(&node_addr);

//        if( node_addr.node_ptr)
//        {
//               // config_07A = \
//               //        (CONFIG_INFO_TYPE(TYPE_SENSOR_07A_SLAVE) *) node_addr.node_ptr->node_config_data;

//               printf("91A name %s \n",node_addr.node_ptr->dev_description);
//        }
//        else
//        {
//               printf("the node is null\n");
//        }
      
}





/**
 * @brief 根据多级地址，找到91A节点，调用91A的初始化函数初始化，然后对节点的链表进行读写操作。
 * 
 */
void TEST_find_91A_node_then_init_and_event_list_append()
{
       // // 1、寻找一个91A节点
       //  muti_addr_t node_addr;

       // {
       //        printf("find by addr_90A_91a muti addr \n");

       //        // 1.1、创建一个多级地址信息
       //        circuit_node_addr_t addr_90A_91a[] = {\
       //                                                  {SELF_CIRCUIT_CAN_IN1, 0}\
       //                                                  };
       //        node_addr.addr_arry_ptr = addr_90A_91a;
       //        node_addr.addr_num = ARRY_SIZE(addr_90A_91a);;

       //        // 1.2、根据多级地址 找到节点
       //        get_node_from_master_tree_by_muti_addr(&node_addr);
       // }
       

       // // 2、对找到的节点进行初始化
       // if( node_addr.node_ptr)
       // {
       //        circuit_node_t  *temp_node = node_addr.node_ptr ;

       //        // 2.1、根据 设备类型 找到设备的操作函数
       //        node_operate_irf_t       *op_ptr;       /** 模块的操作函数指针 */
       //        op_ptr = get_op_irf_by_circuit_node_type(temp_node->node_type);

       //        // 2.2、初始化 该节点的实时状态
       //        op_ptr->irfInit(temp_node, NULL); 

       //        // 2.3、创建 局部变量：独有状态链表指针,指向节点的链表头，进行读写
       //        RT_DATA_TYPE(TYPE_CTR_CW1320_91A) *rt_91A = temp_node->node_rt_data;
       //        list_head_node *list = &rt_91A->gas_exth_zone_1.gas_zone_event_list;

       //        // 2.4、上报的几个报警信息，下边进行 读取测试：
       //         report_data_t data1 = 
       //        {
       //               .evt_type = 1,
       //               .dev_addr.master_index = 11,
       //               .dev_addr.node_index = 2,
       //               .dev_addr.relay_index = 3,
       //               .occur_time = get_century_seconds()
       //        };

       //         report_data_t data2 = 
       //        {
       //               .evt_type = 1,
       //               .dev_addr.master_index = 22,
       //               .dev_addr.node_index = 2,
       //               .dev_addr.relay_index = 3,
       //               .occur_time = get_century_seconds()
       //        };

       //         report_data_t data3 = 
       //        {
       //               .evt_type = 1,
       //               .dev_addr.master_index = 33,
       //               .dev_addr.node_index = 2,
       //               .dev_addr.relay_index = 3,
       //               .occur_time = get_century_seconds()
       //        };

       //         report_data_t data4 = 
       //        {
       //               .evt_type = 1,
       //               .dev_addr.master_index = 44,
       //               .dev_addr.node_index = 2,
       //               .dev_addr.relay_index = 3,
       //               .occur_time = get_century_seconds()
       //        };

       //        // 建一个用于读取的变量
       //         report_data_t data_read;

       //        list_write(list, data1);
       //        list_write(list, data2);
       //        list_write(list, data3);
       //        list_write(list, data4);

       //        for(int num = 1; num < 5; num++)
       //        {
       //               list_read(list, num, &data_read) ;

       //               printf("%d \n", data_read.dev_addr.master_index);
       //        }
       // }
       // printf("TEST_find_91A_node_then_init_and_event_list_append end \n");

}








/**
 * @brief 通过 多级地址 找到对应节点
 * 
 */
void TEST_auto_find_node_by_muti_address()
{
       /*****************通过节点的多级地址与节点类型 查找节点信息*********************** */
       CONFIG_INFO_TYPE(TYPE_SENSOR_07A_SLAVE)  *config_07A; 
       muti_addr_t node_addr;

       config_data_store_t  config_data;


       printf("1、------addr_90A_91a_91a_07A. config.dev name:");

       circuit_node_addr_t addr_90A_91a_91a_07A[] = {                          \
                                          {SELF_CIRCUIT_CAN_IN1, 0},\
                                          {MOD_91A_CIRCUIT_PDFB1,0}, \
                                          {MOD_91A_CIRCUIT_PDFB1,1}\
                                   };

       node_addr.addr_arry_ptr = addr_90A_91a_91a_07A;
       node_addr.addr_num = ARRY_SIZE(addr_90A_91a_91a_07A);

       get_node_from_master_tree_by_muti_addr(&node_addr);

       if( node_addr.node_ptr)
       {
              // config_07A = \
              //        (CONFIG_INFO_TYPE(TYPE_SENSOR_07A_SLAVE) *) node_addr.node_ptr->node_config_data;

              printf("07A name %s \n",node_addr.node_ptr->dev_description);
       }
      
       printf("2、------addr_90A_relymod_07A. config.dev name:");

       circuit_node_addr_t addr_90A_relymod_07A[] = {                       \
                                                 {SELF_CIRCUIT_CAN_IN1, 1}, \
                                                 {MOD_RELAY_MOD_CIRCUIT,1}  \
                                                 };

       node_addr.addr_arry_ptr = addr_90A_relymod_07A;
       node_addr.addr_num = ARRY_SIZE(addr_90A_relymod_07A);

       get_node_from_master_tree_by_muti_addr(&node_addr);

       if( node_addr.node_ptr)
       {
              config_07A = \
                     (CONFIG_INFO_TYPE(TYPE_SENSOR_07A_SLAVE) *) node_addr.node_ptr->node_config_data;

              printf("07A name %s \n",node_addr.node_ptr->dev_description);
       }


       printf("3、------addr_90A_91A_relymod_07A. config.dev name:");

       circuit_node_addr_t addr_90A_91A_relymod_07A[] = {                              \
                                                 {SELF_CIRCUIT_CAN_IN1, 0},\
                                                 {MOD_91A_CIRCUIT_PDFB1, 1},\
                                                 {MOD_RELAY_MOD_CIRCUIT,0}\
                                           };

       node_addr.addr_arry_ptr = addr_90A_91A_relymod_07A;
       node_addr.addr_num = ARRY_SIZE(addr_90A_91A_relymod_07A);
       
       get_node_from_master_tree_by_muti_addr(&node_addr);

       if( node_addr.node_ptr)
       {
              config_07A = \
                     (CONFIG_INFO_TYPE(TYPE_SENSOR_07A_SLAVE) *) node_addr.node_ptr->node_config_data;

              printf("07A name %s \n",node_addr.node_ptr->dev_description);
       }

       if( node_addr.node_ptr)
       {
              get_node_config_data(node_addr.node_ptr, &config_data);
              if(config_data.config_data_store_ptr)
              {
                     switch (config_data.node_type)
                     {
                     case TYPE_SENSOR_07A_SLAVE:
                            {
                                   /**> 确定对应设备类型，创建对应类型的变量*/
                                   CONFIG_INFO_TYPE(TYPE_SENSOR_07A_SLAVE) config_07A;
                                   /**> 将类型转换一下  */
                                   config_07A = config_data.config_data_store_ptr->TYPE_SENSOR_07A_SLAVE_info_config;
                                   printf("07A uc code %s\n",config_07A.UC_code);
                                   break;  
                            }
                     
                     
                     default:
                     break;
                     }
              }
       }
       


printf("\n============================================= \n");
}


